package cn.jtool.dig.common.netty.supports;

import org.apache.commons.lang3.StringUtils;

import java.io.UnsupportedEncodingException;

/**
 * 数据转换工具
 */
public class Convert {

    private final static byte[] hex = "0123456789ABCDEF".getBytes();

    public static String formatCommandToHex(Integer commandId){
        return Convert.fillZeroHead(Integer.toHexString(commandId), 4);
    }

    /**
     * 从左开始找,找到第一个有效字节
     * @param bytes
     * @return
     */
    public static byte[] findFristValidCharacter(byte[] bytes) {
        int index = bytes.length;
        for (int i = bytes.length - 1; i >= 0; i--) {
            if (bytes[i] == 0x00) {
                index = i;
            } else {
                break;
            }
        }
        return ArraysUtils.subarrays(bytes, 0, index);
    }

    /**
     * 字节转GBK字符串
     * @param bytes
     * @return
     */
    public static String bytesToGbkString(byte[] bytes) {
        try {
            if(bytes != null){
                return new String(bytes, "gbk");
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 字节转UTF8字符串
     * @param bytes
     * @return
     */
    public static String bytesToUtf8String(byte[] bytes) {
        try {
            return new String(bytes, "utf8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 字符串转GBK <br>
     * mixStr2Hex
     *
     * @param str
     * @return
     */
    public static String strToGbk(String str) {
        byte[] bytes = null;
        try {
            bytes = str.getBytes("GBK");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        StringBuilder sb = new StringBuilder(bytes.length * 2);
        for (int i = 0; i < bytes.length; i++) {
            sb.append("0123456789ABCDEF".charAt((bytes[i] & 0xf0) >> 4));
            sb.append("0123456789ABCDEF".charAt((bytes[i] & 0x0f) >> 0));
        }
        return sb.toString();
    }

    /**
     * 判断当前数字二进制位是否为1
     * @param number
     * @param index
     * @return
     */
    public static boolean isNumberBinary(Number number, Integer index){
        String binary = Long.toBinaryString(number.longValue());
        if(binary.length() <= index){
            return false;
        }
        String indexValue = binary.substring(binary.length() - index - 1, binary.length() - index);
        return StringUtils.equals(indexValue, "0") ? false : true;
    }

    /**
     * 删除字符串前面的0
     *
     * @param str 需要去除零的字符串
     * @return 删除前面有0字符的字符串
     */
    public static String removeHeadZero(String str) {
        while (true) {
            if (str.startsWith("0")) {
                str = str.substring(1);
            } else {
                return str;
            }
        }
    }


    /**
     * 删除字节的0
     *
     * @param bytes 需要去除零的字符串
     * @param dir 方向 true：左边 false:右边
     * @return
     */
    public static byte[] removeZero(byte[] bytes, boolean dir) {
        for(int i = bytes.length - 1; i >= 0; i --){
            if(bytes[i] != 0x00){
                return ArraysUtils.subarrays(bytes, 0, i + 1);
            }
        }
        return null;
    }



    /**
     * 字节数组转换到十六进制字符串
     *
     * @param bytes {@link Byte}字节数组
     * @return {@link String} 十六进制字符串
     */
    public static String bytesToHexString(byte[] bytes) {
        byte[] buff = new byte[2 * bytes.length];
        for (int i = 0, length = bytes.length; i < length; i++) {
            buff[2 * i] = hex[(bytes[i] >> 4) & 0x0f];
            buff[2 * i + 1] = hex[bytes[i] & 0x0f];
        }
        return new String(buff);
    }

    /**
     * 十六进制字符串转换到字节数组
     *
     * @param hexstr {@link String} 十六进制字符串
     * @return {@link Byte}[]字节数组
     */
    public static byte[] hexStringToBytes(String hexstr) {
        byte[] b = new byte[hexstr.length() / 2];
        int j = 0;
        for (int i = 0, length = b.length; i < length; i++) {
            char c0 = hexstr.charAt(j++);
            char c1 = hexstr.charAt(j++);
            b[i] = (byte) ((parse(c0) << 4) | parse(c1));
        }
        return b;
    }

    private static int parse(char c) {
        if (c >= 'a')
            return (c - 'a' + 10) & 0x0f;
        if (c >= 'A')
            return (c - 'A' + 10) & 0x0f;
        return (c - '0') & 0x0f;
    }

    /**
     * 十进制转十六进制
     *
     * @param number int 十进制
     * @param x      int 位数
     * @return
     */
    public static String decimalToHexadecimal(long number, int x) {
        String hex = Long.toHexString(number).toUpperCase();
        return fillZeroHead(hex, x);
    }

    /**
     * 填充0
     *
     * @param text   {@link Object} 需要补0的对象
     * @param length {@link Integer} 补0后的长度
     * @return {@link String}
     */
    public static String fillZeroHead(Object text, int length) {
        StringBuilder builder = new StringBuilder(length);
        if (text == null) {
            for (int i = 0; i < length; i++)
                builder.append("0");
        } else {
            for (int i = String.valueOf(text).length(); i < length; i++) {
                builder.append("0");
            }
            builder.append(text);
        }
        return builder.toString();
    }

    /**
     * 整形转字节
     *
     * @param number
     * @param size
     * @return
     */
    public static byte[] longTobytes(long number, int size) {
        byte[] b = new byte[size];
        for (int i = 0; i < size; i++) {
            b[i] = (byte) (number >> 8 * (size - i - 1) & 0xFF);
        }
        return b;
    }

    /**
     * 字节转整形<br>
     * 最大支持4字节
     *
     * @param bytes
     * @param size
     * @return
     */
    public static long byte2Long(byte[] bytes, int size) {
        long intValue = 0l;
        for (int i = 0; i < bytes.length; i++) {
            intValue |= (long) (bytes[i] & 0xFF) << (8 * (size - i - 1));
        }
        return intValue;
    }

    /**
     * 按照java字节序处理
     *
     * @param bytes
     * @param size
     * @return
     */
    public static int byte2Int(byte[] bytes, int size) {
        int intValue = 0;
        for (int i = 0; i < bytes.length; i++) {
            intValue += (bytes[i] & 0xFF) << (8 * (size - i - 1));
        }
        return intValue;
    }

    /**
     * 整形转字节
     *
     * @param number
     * @param size
     * @return
     */
    public static byte[] intTobytes(int number, int size) {
        byte[] b = new byte[size];
        for (int i = 0; i < size; i++) {
            b[i] = (byte) (number >> 8 * (size - i - 1) & 0xFF);
        }
        return b;
    }

    /**
     * 国标的时间转为时间字符串yyyy-mm-dd HH-mm-ss
     *
     * @param bytes 国标时间格式
     * @return 时间字符串
     */
    public static String gbDateToString(byte[] bytes) {
        StringBuffer sb = new StringBuffer();
        sb.append("20").append(fillZeroHead(bytes[0], 2)).append("-");
        sb.append(fillZeroHead(bytes[1], 2)).append("-");
        sb.append(fillZeroHead(bytes[2], 2)).append(" ");
        sb.append(fillZeroHead(bytes[3], 2)).append(":");
        sb.append(fillZeroHead(bytes[4], 2)).append(":");
        sb.append(fillZeroHead(bytes[5], 2));
        return sb.toString();
    }

    /**
     * 国标的时间转成国标的字符串  yyMMddHHmmss
     */
    public static String bytesToDateString(byte[] bytes) {
        StringBuffer sb = new StringBuffer();
        sb.append(fillZeroHead(bytes[0], 2));
        sb.append(fillZeroHead(bytes[1], 2));
        sb.append(fillZeroHead(bytes[2], 2));
        sb.append(fillZeroHead(bytes[3], 2));
        sb.append(fillZeroHead(bytes[4], 2));
        sb.append(fillZeroHead(bytes[5], 2));
        return sb.toString();
    }

    /**
     * 数字转16进制
     * @param number
     * @param length
     * @return
     */
    public static String numberToHex(long number, int length){
        return Convert.fillZeroHead(Long.toHexString(number), length);
    }

    /**
     * 16进制转2进制
     * @param bytes
     * @param size
     * @return
     */
    public static String hexToBinary(byte[] bytes, int size) {

        int i = Convert.byte2Int(bytes, size);
        String binary = Integer.toBinaryString(i);
        return binary;

    }
}
